package org.wattdepot.cli.command;

import java.util.List;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.source.jaxb.Source;

/**
 * Abstract class that should be extended by all CLI commands.
 * 
 * @author George Lee
 *
 */
public abstract class WattDepotCliCommand {
  /** Error message to display for unknown commands. */
  protected static final String UNKNOWN_COMMAND = "Unknown command." 
    + " Type help for available commands.";
  /** Error message to display for parameter count errors. */
  protected static final String PARAMETER_COUNT_ERROR = "Incorrect number of arguments.";
  /** Error message to display for invalid parameter errors. */
  protected static final String PARAMETER_ERROR = "Invalid parameter ";
  /** Error message to display for invalid interval parameters. */
  protected static final String INTERVAL_ERROR = "Invalid interval ";
  /** Error message to display for invalid range for an interval. */
  protected static final String RANGE_ERROR = "Interval must be greater than 0.";
  /** Error message to display for invalid timestamp parameters. */
  protected static final String TSTAMP_ERROR = "Could not create timestamp from ";
  /** Error message to display for unknown source errors. */
  protected static final String SOURCE_ERROR = "Invalid source ";
  /** Error message to display for connection error. */
  protected static final String CONNECTION_ERROR = "Connection error ";
  /** Error message to display for bad xml errors. */
  protected static final String BAD_XML_ERROR = "Retrieved a bad result from Watt Depot";
  /** Format string to convert a double to a integer string.*/
  protected static final String FORMAT_DOUBLE = "%.0f";
  /** Determines whether the command should be power generated or consumed. */
  protected enum PowerCommandType {
    /**Command type is 'power generated'.*/
    POWER_GENERATED, 
    /**Command type is 'power consumed'.*/
    POWER_CONSUMED
  }
  /** Determines the statistic to use in the 'list power generated/consumed' method. */
  protected enum StatisticType {
    /**Statistic type is "maximum".*/
    STAT_MAX, 
    /**Statistic type is "minimum".*/
    STAT_MIN, 
    /**Statistic type is "average".*/
    STAT_AVG
  }

  /** Represents the WattDepotClient that will process our commands.*/
  protected WattDepotClient client;
  
  /**
   * Initializes the client.  Note that this class cannot be instantiated.
   * 
   * @param client The client that will process our commands.
   */
  public WattDepotCliCommand(WattDepotClient client) {
    this.client = client;
  }
  
  /**
   * Returns the help string for the command.
   * 
   * @return Information about how to invoke the command.
   */
  public abstract String getHelp();
  
  /**
   * Implements a WattDepot command. Must be implemented by subclasses.
   * 
   * @param command The command to process.
   * @return The result of the command.
   */
  public abstract String doCommand(String command);
  
  /**
   * Reports an error by a WattDepot command.  Uses the help string to report
   * usage information.
   * 
   * @param error The error that occurred.
   * @return The error message along with the help string for the command.
   */
  protected String reportError(String error) {
    return error + " Usage: " + this.getHelp();
  }
  
  /**
   * Returns the error message for invalid commands.
   * 
   * @param command The erroneous command.
   * @return A string that states that the command was invalid.
   */
  public static String reportUnknownCommand(String command) {
    return UNKNOWN_COMMAND;
  }
  
  /**
   * Get all non-virtual sources inside a given source.
   * 
   * @param sourceList the array list to hold all the non-virtual sources
   * @param source the current source
   * @param client the current wattdepot client
   * @throws NotAuthorizedException exception
   * @throws ResourceNotFoundException exception
   * @throws BadXmlException exception
   * @throws MiscClientException exception
   */
  public static void getNonVirtualSources(List<Source> sourceList, Source source, 
      WattDepotClient client) throws NotAuthorizedException, 
      ResourceNotFoundException, BadXmlException, MiscClientException {
    if (source.isVirtual()) {
      List<String> subSourceNames = source.getSubSources().getHref();
      for (String tempSourceName : subSourceNames) {
        Source tempSource = client.getSource(
          tempSourceName.substring(tempSourceName.indexOf("SIM")));
        getNonVirtualSources(sourceList, tempSource, client);
      }
    }
    else {
      sourceList.add(source);
    }
  }
}
